package com.oauth.yahoo.server.service;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.annotation.PostConstruct;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;

import org.json.JSONArray;
import org.json.JSONObject;
import org.scribe.oauth.Scribe;
import org.scribe.oauth.Token;
import org.springframework.beans.factory.annotation.Required;

import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.beans.OAuthConfigBean;
import com.oauth.common.server.beans.OAuthRequestToken;
import com.oauth.service.generic.OAuthService;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.service.generic.exception.OAuthServiceException;
import com.oauth.yahoo.client.beans.Mail;
import com.oauth.yahoo.server.beans.YahooRequestToken;
import com.oauth.yahoo.server.beans.YahooServiceBean;
import com.oauth.yahoo.server.util.YahooUtil;

public class YahooOAuthServiceImpl implements YahooOAuthService {

	private OAuthProvider oauthProvider;

	private OAuthService mOAuthService;

	private OAuthConfigBean mOAuthConfigBean;

	/**
	 * @param pOAuthService
	 *            the oAuthService to set
	 */
	@Required
	public void setOAuthService(OAuthService pOAuthService) {
		mOAuthService = pOAuthService;
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	@Required
	public void setOAuthConfigBean(OAuthConfigBean pOAuthConfigBean) {
		mOAuthConfigBean = pOAuthConfigBean;
	}

	@PostConstruct
	public void initialise() {
		oauthProvider = new CommonsHttpOAuthProvider(
				"https://api.login.yahoo.com/oauth/v2/get_request_token",
				"https://api.login.yahoo.com/oauth/v2/get_token",
				"https://api.login.yahoo.com/oauth/v2/request_auth");
	}

	private OAuthConsumer getOAuthConsumer() {
		return new CommonsHttpOAuthConsumer(mOAuthConfigBean.getConsumerKey(), mOAuthConfigBean
				.getConsumerSecret());
	}

	@Override
	public YahooRequestToken getRequestToken() throws Exception {
		Scribe scribe = new Scribe(props);
		Token requestToken = scribe.getRequestToken();
		//httpSession.setAttribute(YAHOO_REQUEST_TOKEN, requestToken);
		String tokenString = requestToken.getToken();
		
//		OAuthConsumer consumer = getOAuthConsumer();
//		String authUrl = oauthProvider.retrieveRequestToken(consumer, mOAuthConfigBean
//				.getCallBackUrl());
		System.out.println(tokenString);
		return new YahooRequestToken(requestToken.getToken(), requestToken.getSecret(), "https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token="+requestToken.getToken()+"&oauth_callback=http://oauth-local.appspot.com:8888/yahoo.html?gwt.codesvr=127.0.0.1:9997");
	}

	@Override
	public OAuthAccessToken getAccessTokenFromDB(Long pMemberId) throws Exception {
		OAuthServiceBean token = null;
		token = mOAuthService.getToken(pMemberId, YahooServiceBean.class);
		if (token != null) {
			return new OAuthAccessToken(token.getAccessToken(), token.getAccessTokenSecret());
		}
		return null;
	}

	@Override
	public void persistAccessToken(OAuthAccessToken pAccessToken, Long pMemberId)
			throws OAuthServiceException {
		YahooServiceBean serviceBean = new YahooServiceBean();
		serviceBean.setAccessToken(pAccessToken.getToken());
		serviceBean.setAccessTokenSecret(pAccessToken.getTokenSecret());
		serviceBean.setMemberId(pMemberId);
		// serviceBean.setTwitterId(twitter.getUserId());
		mOAuthService.persistToken(serviceBean); // persist in db for future
		// use.
	}

	@Override
	public OAuthAccessToken getAccessTokenFromRequestToken(OAuthRequestToken pOAuthTokenBean,
			String pOAuthVerifier) throws Exception {
		Scribe scribe = new Scribe(props);
		Token requestToken = new Token(pOAuthTokenBean.getToken(),pOAuthTokenBean.getTokenSecret());
		System.out.println("Try to get access token from request token:"+requestToken);
		System.out.println("Verifier:"+pOAuthVerifier);
		Token accessToken = scribe.getAccessToken(requestToken,
				pOAuthVerifier);
//		OAuthConsumer consumer = getOAuthConsumer();
//		consumer.setTokenWithSecret(pOAuthTokenBean.getToken(), pOAuthTokenBean.getTokenSecret());
//		oauthProvider.retrieveAccessToken(consumer, pOAuthVerifier);
		return new OAuthAccessToken(accessToken.getToken(), accessToken.getSecret());

	}

	@Override
	public List<Mail> getYahooMail(Long pMemberId) throws Exception {
		//OAuthConsumer consumer = getOAuthConsumer();
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		
		// In Yahoo, you need to get the guid before getting any details.
		// TODO: Make sure it is required for mail apis.
		
		Scribe scribe = new Scribe(props);
		
		String token = accessToken.getToken();
		String tokenSecret = accessToken.getTokenSecret();
		System.out.println("Token:"+token);
		System.out.println("TokenSecret:"+tokenSecret);
		Token scribeAccessToken = new Token(token,tokenSecret);
		//String guid = YahooUtil.getGuid(scribe, scribeAccessToken);
		
		//String s = "AD_request1=GetUserData,[{}]  AC_request3=ListFolders,[{}]";
		//JSONArray jsonObjSend = new JSONArray(s);
		
		//System.out.println("GUID="+guid);
		JSONObject data = YahooUtil.getData(scribe, null, scribeAccessToken);
		
		
		//consumer.setTokenWithSecret(accessToken.getToken(), accessToken.getTokenSecret());
		//JSONArray jsonObjSend = null;
		//JSONObject data = YahooUtil.getData(consumer, jsonObjSend);
		//System.out.println(data.toString());
		return getYahooMail(data);

	}

	private List<Mail> getYahooMail(JSONObject pData) {
		// TODO Auto-generated method stub
		return new ArrayList<Mail>(0);
	}
	
	private static final String YAHOO_ACCESS_TOKEN = "yahooAccessToken";
	private static final String YAHOO_REQUEST_TOKEN = "yahooRequestToken";
	private static final ResourceBundle applicationProps = ResourceBundle
			.getBundle("yahooFriends", Locale.getDefault());
	
	private static final Properties props = convertResourceBundleToProperties(applicationProps);
	/**
	 * Convert ResourceBundle into a Properties object.
	 * 
	 * @param resource
	 *            a resource bundle to convert.
	 * @return Properties a properties version of the resource bundle.
	 */
	private static Properties convertResourceBundleToProperties(
			ResourceBundle resource) {
		System.out.println("Parsing resource bundle");
		Properties properties = new Properties();

		Enumeration<String> keys = resource.getKeys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement();
			properties.put(key, resource.getString(key));
			System.out.println("Parsing resource bundle Key,Value:"+key+","+resource.getString(key));
		}

		return properties;
	}
	
}
